Date.prototype.format = function(e) {
    let t = function(e, t) {
        let i = ""
          , s = e < 0
          , o = String(Math.abs(e));
        return o.length < t && (i = new Array(t - o.length + 1).join("0")),
        (s ? "-" : "") + i + o
    };
    if ("string" != typeof e)
        return this.toString();
    let i = function(t, i) {
        e = e.replace(t, i)
    }
      , s = this.getFullYear()
      , o = this.getMonth() + 1
      , n = this.getDate()
      , r = this.getHours()
      , a = this.getMinutes()
      , d = this.getSeconds()
      , l = this.getMilliseconds();
    return i(/yyyy/g, t(s, 4)),
    i(/yy/g, t(parseInt(s.toString().slice(2), 10), 2)),
    i(/MM/g, t(o, 2)),
    i(/M/g, o),
    i(/dd/g, t(n, 2)),
    i(/d/g, n),
    i(/HH/g, t(r, 2)),
    i(/H/g, r),
    i(/hh/g, t(r % 12, 2)),
    i(/h/g, r % 12),
    i(/mm/g, t(a, 2)),
    i(/m/g, a),
    i(/ss/g, t(d, 2)),
    i(/s/g, d),
    i(/SSS/g, t(l, 3)),
    i(/S/g, l),
    e
}
,
new URL(location.href).protocol.startsWith("http") && (window.chrome = window.chrome || {},
window.chrome.storage = {
    local: {
        get(e, t) {
            let i = [];
            [].concat(e).forEach(e=>{
                i[e] = localStorage.getItem(e)
            }
            ),
            t && t(i)
        },
        set(e, t) {
            Object.keys(e).forEach(t=>localStorage.setItem(t, e[t])),
            t && t()
        }
    }
}),
!RegExp.prototype.toJSON && Object.defineProperty(RegExp.prototype, "toJSON", {
    value: RegExp.prototype.toString
});
let editor = null;
const PAGE_MONKEY_LOCAL_STORAGE_KEY = "PAGE-MODIFIER-LOCAL-STORAGE-KEY";
new Vue({
    el: "#pageContainer",
    data: {
        editing: !1,
        editCM: {},
        editWithUI: !0,
        cachedMonkeys: []
    },
    mounted: function() {
        this.editCM = this.getANewCM(),
        window.onbeforeunload = (e=>{
            this.editCM.unSaved && ((e || window.event).returnValue = "当前还有未保存的数据，确定要离开么？")
        }
        ),
        this.getPageMonkeyConfigs(e=>{
            this.cachedMonkeys = (e || []).filter(e=>e.mName && e.mPattern)
        }
        )
    },
    methods: {
        getPageMonkeyConfigs: function(e) {
            chrome.storage.local.get(PAGE_MONKEY_LOCAL_STORAGE_KEY, t=>{
                let i, s = !1;
                if (t && t[PAGE_MONKEY_LOCAL_STORAGE_KEY] ? i = t[PAGE_MONKEY_LOCAL_STORAGE_KEY] || "[]" : (i = localStorage.getItem(PAGE_MONKEY_LOCAL_STORAGE_KEY) || "[]",
                s = !0),
                e && e(JSON.parse(i)),
                s) {
                    let e = {};
                    e[PAGE_MONKEY_LOCAL_STORAGE_KEY] = i,
                    chrome.storage.local.set(e)
                }
            }
            )
        },
        savePageMonkeyConfigs: function(e, t) {
            let i = {};
            i[PAGE_MONKEY_LOCAL_STORAGE_KEY] = JSON.stringify(e),
            chrome.storage.local.set(i),
            t && t()
        },
        getANewCM: function() {
            return {
                id: "mf_" + 1 * new Date,
                mName: "",
                mPattern: "",
                mScript: "",
                mRefresh: 0,
                mDisabled: !1,
                mRequireJs: "",
                mUpdatedAt: (new Date).format("yyyy-MM-dd HH:mm:ss")
            }
        },
        initEditor() {
            editor || (editor = CodeMirror.fromTextArea(this.$refs.mScript, {
                mode: "text/javascript",
                lineNumbers: !0,
                matchBrackets: !0,
                styleActiveLine: !0,
                lineWrapping: !0
            })).on("keydown", (e,t)=>{
                if ((t.metaKey || t.ctrlKey) && "KeyS" === t.code)
                    return this.saveMonkey(),
                    t.preventDefault(),
                    t.stopPropagation(),
                    !1
            }
            )
        },
        toggleEditMode() {
            let e = this.editCM.unSaved;
            if (this.editWithUI)
                editor.setValue(this.deflateMonkey(this.getEditMonkey()));
            else {
                let e = this.inflateMonkey(editor.getValue());
                this.editCM = {
                    ...e
                },
                this.$nextTick(()=>{
                    editor.setValue(this.editCM.mScript)
                }
                )
            }
            this.editCM.unSaved = e,
            this.editWithUI = !this.editWithUI
        },
        createMonkey: function() {
            this.editing = !0,
            this.editCM.unSaved = !0,
            this.editCM = this.getANewCM(),
            this.initEditor(),
            this.$nextTick(()=>{
                editor.setValue(window.MonkeyNewGuide)
            }
            )
        },
        selectMonkey: function(e) {
            this.editing = !0,
            this.editCM = e,
            this.initEditor(),
            this.$nextTick(()=>{
                editor.setValue(this.editWithUI ? e.mScript : this.deflateMonkey(e))
            }
            )
        },
        getEditMonkey() {
            return this.editWithUI ? (this.editCM.mScript = editor && editor.getValue() || this.editCM.mScript,
            this.editCM.mUpdatedAt = (new Date).format("yyyy-MM-dd HH:mm:ss"),
            this.editCM.mDisabled = !!this.editCM.mDisabled,
            this.editCM) : this.inflateMonkey(editor.getValue())
        },
        saveMonkey: function() {
            let e = this.getEditMonkey();
            !this.cachedMonkeys.some((t,i)=>{
                if (t.id === e.id)
                    return this.cachedMonkeys[i] = e,
                    !0
            }
            ) && e.mName && e.mPattern && this.cachedMonkeys.push(e),
            this.savePageMonkeyConfigs(this.cachedMonkeys, ()=>{
                this.editCM.unSaved = !1,
                this.toast("恭喜，您的操作已成功并生效！")
            }
            )
        },
        closeEditor() {
            this.editCM.unSaved && confirm("检测到当前猴子有修改，是否先保存？") && this.savePageMonkeyConfigs(this.cachedMonkeys, ()=>{
                this.toast("恭喜，您的操作已成功并生效！")
            }
            ),
            this.editing = !1,
            this.editCM.unSaved = !1
        },
        loadMonkeys(e) {
            if (e && Array.isArray(e) && e.length) {
                let t = "mName,mPattern,mRefresh,mScript,mDisabled,mRequireJs,mUpdatedAt".split(",")
                  , i = e.filter(e=>!("object" != typeof e || (Object.keys(e).forEach(i=>{
                    !t.includes(i) && "id" !== i && delete e[i]
                }
                ),
                e.mUpdatedAt || (e.mUpdatedAt = (new Date).format("yyyy-MM-dd HH:mm:ss")),
                !Object.keys(e).length)));
                if (i.length) {
                    let e = null;
                    i.forEach(i=>{
                        if (!this.cachedMonkeys.some(s=>{
                            if (i.id === s.id || i.mName === s.mName || i.mPattern === s.mPattern)
                                return null === e && (e = confirm("发现有相同名称或规则的油猴，是否选择覆盖？")),
                                e && (t.forEach(e=>{
                                    s[e] = i[e]
                                }
                                ),
                                s.mUpdatedAt = (new Date).format("yyyy-MM-dd HH:mm:ss")),
                                !0
                        }
                        ) || !1 === e) {
                            let e = {
                                ...i
                            };
                            e.id = this.getANewCM().id,
                            e.mUpdatedAt = (new Date).format("yyyy-MM-dd HH:mm:ss"),
                            this.cachedMonkeys.push(e)
                        }
                    }
                    ),
                    this.savePageMonkeyConfigs(this.cachedMonkeys, ()=>{
                        this.toast("恭喜，您的操作已成功并生效！")
                    }
                    )
                }
            }
        },
        deflateMonkey(e) {
            let t = (e,t)=>String(e).padEnd(20, t || " ")
              , i = [];
            i.push("// ==FeHelperMonkey=="),
            i.push(t("// @reminder") + "请不要删除这部分代码注释，这是FeHelper油猴脚本能正常工作的基本条件！当然，你可以按需修改这里的内容！"),
            i.push(t("// @id") + e.id),
            i.push(t("// @name") + e.mName),
            i.push(t("// @url-pattern") + e.mPattern),
            i.push(t("// @enable") + !e.mDisabled);
            let s = (e.mRequireJs || "").split(/[\s,，]+/).filter(e=>e.length);
            return (s = Array.from(new Set(s))).forEach(e=>{
                i.push(t("// @require-js") + e)
            }
            ),
            s.length || i.push(t("// @require-js")),
            i.push(t("// @auto-refresh") + e.mRefresh),
            i.push(t("// @updated") + e.mUpdatedAt),
            i.push("// ==/FeHelperMonkey==\n\n"),
            i.push(e.mScript),
            i.join("\n")
        },
        inflateMonkey(e) {
            if (0 !== e.indexOf("// ==FeHelperMonkey=="))
                throw new Error("wrong file header");
            if (-1 === e.indexOf("// ==/FeHelperMonkey=="))
                throw new Error("wrong file header");
            let[t,i] = e.split("// ==/FeHelperMonkey==")
              , s = this.getANewCM();
            if (s.mScript = (i || "").trim(),
            t.split("\n").forEach(e=>{
                if (e.startsWith("// @id"))
                    s.id = e.split("// @id")[1].trim();
                else if (e.startsWith("// @name"))
                    s.mName = e.split("// @name")[1].trim();
                else if (e.startsWith("// @url-pattern"))
                    s.mPattern = e.split("// @url-pattern")[1].trim();
                else if (e.startsWith("// @enable"))
                    s.mDisabled = "false" === e.split("// @enable")[1].trim();
                else if (e.startsWith("// @auto-refresh"))
                    s.mRefresh = parseInt(e.split("// @auto-refresh")[1].trim());
                else if (e.startsWith("// @updated"))
                    s.mUpdatedAt = e.split("// @updated")[1].trim();
                else if (e.startsWith("// @require-js")) {
                    let t = (s.mRequireJs || "").split(/[\s,，]+/).filter(e=>e.length);
                    (t = Array.from(new Set(t))).push(e.split("// @require-js")[1].trim()),
                    s.mRequireJs = t.join(",")
                }
            }
            ),
            !s.mName || !s.mPattern)
                throw new Error("wrong file format,no name or url-pattern");
            return s
        },
        importMonkey: function() {
            let e = document.getElementById("fileInput");
            e || ((e = document.createElement("input")).id = "fileInput",
            e.type = "file",
            e.accept = "application/json,text/javascript",
            e.style.cssText = "position:relative;top:-1000px;left:-1000px;",
            e.onchange = (t=>{
                let i = new FileReader;
                i.readAsText(e.files[0], "utf-8"),
                i.onload = (t=>{
                    let i = t.target.result;
                    if (/\.js$/.test(e.files[0].name))
                        try {
                            let e = this.inflateMonkey(i);
                            this.loadMonkeys([e])
                        } catch (e) {
                            this.toast("当前选择的js文件不符合FeHelper Monkey脚本文件格式！")
                        }
                    else if (/\.json$/.test(e.files[0].name))
                        try {
                            let e = JSON.parse(i.replace(/^\/\*[^\*]*\*\//, ""));
                            this.loadMonkeys(e)
                        } catch (e) {
                            this.toast("当前选择的JSON配置文件格式不正确！")
                        }
                }
                )
            }
            ),
            document.body.appendChild(e)),
            e.click()
        },
        exportMonkey: function(e) {
            (e=>{
                let t = new Blob([this.deflateMonkey(e)],{
                    type: "application/octet-stream"
                });
                if ("undefined" != typeof chrome && chrome.permissions)
                    chrome.permissions.request({
                        permissions: ["downloads"]
                    }, i=>{
                        i ? chrome.downloads.download({
                            url: URL.createObjectURL(t),
                            saveAs: !0,
                            conflictAction: "overwrite",
                            filename: `FhMonkey-${e.mName}.js`
                        }) : this.toast("必须接受授权，才能正常导出！")
                    }
                    );
                else {
                    let i = document.getElementById("btnDownloadMonkey");
                    i || ((i = document.createElement("a")).setAttribute("id", "btnDownloadMonkey"),
                    i.style.cssText = "position:absolute;top:-1000px;left:-1000px",
                    document.body.appendChild(i)),
                    i.setAttribute("download", `FhMonkey-${e.mName}.js`),
                    i.setAttribute("href", URL.createObjectURL(t)),
                    i.click()
                }
            }
            )(e)
        },
        removeMonkey: function(e) {
            confirm("你确定要删除所有的油猴吗，此操作不可撤销！") && (this.cachedMonkeys = e ? this.cachedMonkeys.filter(t=>t.id !== e.id) : [],
            this.savePageMonkeyConfigs(this.cachedMonkeys, ()=>{
                this.toast("恭喜，您的操作已成功并生效！")
            }
            ))
        },
        disableMonkey: function(e) {
            e ? (this.cachedMonkeys.some(t=>{
                if (t.id === e.id)
                    return t.mDisabled = !e.mDisabled,
                    t.mUpdatedAt = (new Date).format("yyyy-MM-dd HH:mm:ss"),
                    !0
            }
            ),
            this.savePageMonkeyConfigs(this.cachedMonkeys, ()=>{
                this.toast(`猴子「 ${e.mName} 」相关配置已修改成功！`)
            }
            )) : confirm("停用油猴后，可单独编辑启用；是否继续此操作？") && (this.cachedMonkeys.forEach(e=>{
                e.mDisabled = !0,
                e.mUpdatedAt = (new Date).format("yyyy-MM-dd HH:mm:ss")
            }
            ),
            this.savePageMonkeyConfigs(this.cachedMonkeys, ()=>{
                this.toast("所有猴子均已停用！")
            }
            ))
        },
        loadDemo() {
            confirm("郑重声明：这个Demo是在你打开百度网站时，自动搜索FeHelper，这就是一个用于演示油猴的示例！！！所以，请记得体验完以后自行停用这个Demo！！！！！！！要不然，你一定会误会作者耍流氓，那作者就真的心凉了。。。") && this.loadMonkeys(MonkeyTpl)
        },
        toast(e) {
            window.clearTimeout(window.feHelperAlertMsgTid);
            let t = document.querySelector("#fehelper_alertmsg");
            if (t)
                t.innerHTML = e,
                t.style.display = "block";
            else {
                let i = document.createElement("div");
                i.innerHTML = '<div id="fehelper_alertmsg">' + e + "</div>",
                t = i.childNodes[0],
                document.body.appendChild(t)
            }
            window.feHelperAlertMsgTid = window.setTimeout(function() {
                t.style.display = "none"
            }, 1e3)
        }
    }
});
